﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ViewModel;

namespace Announcer
{
    class ActivityMonitor
    {
        static bool stop = false;

        // Create a TCP/IP socket.
        // static Socket announce = null;

        public static void Start()
        {
            // Data buffer for incoming data.
            byte[] bytes = new Byte[1024];
            // Establish the local endpoint for the socket.
            // Dns.GetHostName returns the name of the 
            // host running the application.
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            Service.Announcer.SetAnnouncerIp(ipAddress.ToString());

            // IPEndPoint localEndPoint = new IPEndPoint(ipAddress, ActiveSession.Port);

            try
            {
                byte[] msg;
                string str;
                List<int> issueIds = new List<int>();
                IPEndPoint iep2 = null;
                List<Issue> issues = new List<Issue>();
                while (!stop)
                {                    
                    issueIds = Service.Announcer.GetItemsToAnnounce();

                    if (issueIds.Count > 0)
                    {
                        issues = Service.Announcer.GetItemsToBeNotified(issueIds);
                        //send to listener                        
                        var receivers = issues.SelectMany(x => x.Assignee).ToList().Distinct().ToList();
                        foreach (var item in receivers)
                        {
                            using (Socket announce = new Socket(AddressFamily.InterNetwork,
                                SocketType.Stream, ProtocolType.Tcp))
                            {
                                iep2 = new IPEndPoint(IPAddress.Parse(item.UDF5), ActiveSession.Port);

                                //List<int> ids = issues.Where(x => x.ShopID == item.ID).Select(y => y.ID).ToList();
                                //str = string.Join("|", ids);

                                var tokens = issues.Where(x => x.ShopID == item.ID).Select(y => new Token() { Title = y.Name, URL = y.Description, Priority = (int)y.Priority }).ToList();
                                str = Helper.Utility.SerializeJSon<List<Token>>(tokens);

                                msg = Encoding.ASCII.GetBytes(str);
                                try
                                {
                                    announce.Bind(iep2);
                                    announce.Listen(1000);

                                    Socket handler = announce.Accept();

                                    handler.Send(msg);
                                    announce.Close();
                                    Service.Announcer.RemoveItemsAfterNotified(issues.Where(x => x.ShopID == item.ID).Select(y => y.ID).ToList());

                                }
                                catch (ArgumentNullException ane)
                                {
                                    Helper.ErrorLogger.WriteLog("ArgumentNullException", ane);
                                }
                                catch (SocketException se)
                                {
                                    Helper.ErrorLogger.WriteLog("SocketException" + iep2.Address, se);
                                }
                                catch (Exception ex)
                                {
                                    Helper.ErrorLogger.WriteLog("Exception", ex);
                                }
                            }
                        }
                    }
                    Thread.Sleep(ActiveSession.AnnouncerDelayInterval * 1000);
                }
            }
            catch (ArgumentNullException ane)
            {
                string s1 = ane.ToString();
            }
            catch (SocketException se)
            {
                string s1 = se.ToString();
            }
            catch (Exception e)
            {
                string s1 = e.ToString();
            }
            finally
            {
                Stop();
            }
        }

        public static void Stop()
        {
            stop = true;
            //announce.Shutdown(SocketShutdown.Both);
            //announce.Close();
        }
    }
}
